#include "../fe8.h"
#include "../gba_hack.h"

#define ItemUnit() (*((u32*)0x3004DF0))
#define ItemSelectIdx() (*((u8*)0x203A954+0x12))
#define GetSelectItem() (*(u16*)(ItemUnit()+0x1E + ItemSelectIdx()*2))
#define GetSelectItemId() (GetSelectItem()&0xff)

static const u8 sum_data[] = {
	0x18, 0x3F,
    0x1F, 0x3E,
    0x23, 0x3B,
    0x00, 0x00,

#define sum_data_idx (4)
#define set_item_summon(item,char_id) \
    (item),(char_id)
#define set_item_summon_len (2)
//set_item_summon(0x4e,0x4),
#include "../hack/sum.h"
    0,0
};

static const u8 summon_class[] = {
#define set_summon_class(char_id,class_id) \
    (char_id),(class_id)
    //set_summon_class(0x4,5),
#include "../hack/sum_class.h"
    0,0,

};

static const u8 summon_item[] = {
#define summon_item_size 4
#define set_summon_item(char_id,item1,item2,item3,item4) \
    char_id,item1,item2,item3,item4
    //set_summon_item(0x4,0x1,0x2,0x3,0x4),
#include "../hack/sum_item.h"
    0,0,0,0,0,0
};

static const u8 summon[] = {
    //0x30,
    0,
};

HACK_DATA(0x08024450)
const u32 _89CFD19_1 = (u32)&sum_data + 1;

HACK_DATA(0x0807d14c)
const u32 _89CFD19_2 = (u32)&sum_data + 1;

HACK_DATA(0x0807d148)
const u32 _89CFD18_3 = (u32)&sum_data + 0;

HACK_DATA(0x080243e0)
const u32 _89CFD18_1 = (u32)&sum_data + 0;

HACK_DATA(0x0807d0ac)
const u32 _89CFD18_2 = (u32)&sum_data + 0;


//一些数据定义
typedef struct{ //0x85C5058
    const char *name;       //"召唤"
    u16     _04,                    //
    _06;        //0x65f,0x61e,      //菜单帮助
    u32     _08;            //0x5700
    void    *func;          //返回1，可以显示，返回3，不能显示
    u32     _10;            //0?
    void    *func2;         //如果点击这个选项，，如果执行nullsub, 则不执行任何
    u32     _18,_1c,_20;    //都为0
}_85C5058;

/*
占领
攻击1
攻击2
杖
乘坐
步行
演奏
舞蹈
盗取
召唤
呼魔
打开
对话
支援
访问
宝箱
开门
武器店
道具店
秘密店
斗技场
救出
放下
接收
转移
物品
交换
运输队
待机


*/

int summon_get(int idx){
    u16 value = GetSelectItemId();//|(char_id<<8);
    if(idx<0){
        int char_id = -1;
        u8  *ptr =  &sum_data[sum_data_idx*2];
        while(*ptr){
            if(value==*ptr){
                char_id = ptr[1];
                break;
            }
            ptr += set_item_summon_len;
        }
        if(char_id>0){
            //直接 3 + char_id
            idx = ptr - (u8*)&sum_data[0];
            idx >>= 1;
        }
    }

    str(0x0203ffd0,idx);
    str(0x0203ffd4,sum_data);

    return idx;
}

int summon_get_class(u8 char_id){
    u8 *ptr = summon_class;
    while(*ptr){
        if(ptr[0]==char_id){
            return ptr[1];
        }
        ptr+=2;
    }
    return 0;
}

int summon_get_item(u8 char_id,int lv){
    u8*ptr = summon_item;
    int idx = 1;
    if(lv>5){
        idx = 2;
    }
    if(lv<10){
        idx = 3;
    }
    if(lv>15){
        idx = 4;
    }
    while(*ptr){
        if(char_id==*ptr){
            return ptr[idx];
        }
        ptr += summon_item_size;
    }
    return 1;
}

/*
807D074 设置召唤的程序

0x88589a4+4 获得职业id

*/
void _807D0D0(){
    asm("mov r0,r0\n");
    asm("JMP807D0D0_r0:\n");
    asm("mov r0,#1\n");
    asm("neg r0,r0\n");
    asm("cmp r5,r0\n");
    asm("mov r0,r5\n");
    asm("bl summon_get");
    asm("mov r5,r0\n");
    asm("mov r1,#1\n");
    asm("neg r1,r1\n");
    asm("cmp r0,r1\n");
    asm("bne _807D0D0_quit\n");
    asm("mov r4,#0\n");
    asm("ldr r0,=0x807D2E9\n");
    asm("bx r0\n");
    asm("_807D0D0_quit:\n");
    asm("ldr r0,=0x807D0DA+1\n"); //不等于-1
    asm("bx r0\n");
}

void _807D074_end(u32 unit){
    //strb(0x3001C31,0x30);
    if(!unit){
        return;
    }

    int lv = getb(get(0x3004DF0)+8);
    //重新设置武器熟练度
    int offset = 0x28;      //斧头
    int class_off = 0x2c;
    //获得职业
    u32 class = get(unit+4);
    int exp = 0x1f;
    if(lv>=20){
        exp = 0xb5;
    }
    else if(lv>15){
        exp = 0xb5;
    }
    else if(lv>10){
        exp = 0x79;
    }
    else if(lv>5){
        exp = 0x47;
    }
    int i;
    for(i=0;i<8;i++){
        if(getb(class+class_off+i)){
            //如果单位存在武器熟练度，则设置
            strb(unit+offset+i,exp);
        }
        else{
            strb(unit+offset+i,0);
        }
    }
}

//处理召唤
u32 _807D074_proc(int v5,u32 v26){
    //int offset = v5 - 0x89CFD18;
    // str(0x0203ffdC,v5);
    // str(0x0203ffd8,sum_data);
    int char_id = getb(v5);
    int class_id = 0x51;
    class_id =  summon_get_class(char_id);
    if(!class_id){
        class_id = 0x51;
    }
    else{
        int item = summon_get_item(char_id,getb(get(0x3004DF0)+8));
        //str(0x0203ffd0,char_id);
        //char_id = 3;
        strb(0x3001C3C,item);        //设置道具
    }

    strb(0x3001C31,class_id);
    strb(0x3001c30,char_id);

    if(!CALLT(0x8017FB0,char_id)){
        CALLT(0x80D6908,v26,0x203A4E8,0x80);
        CALLT(0x80177DC,0x3001C30);
        CALLT(0x80D6908,0x203A4E8,v26,0x80);
    }
    u32 unit = CALLT(0x8017FB0,char_id);

    return unit;
}

void _807D258(){
    asm("mov r0,r0\n");
    asm("JMP807D258_r3:\n");
    asm("mov r0,r5\n");
    asm("mov r1,sp\n");
    asm("bl _807D074_proc\n");
    asm("ldr r1,=0x807D284+1\n");
    asm("bx r1\n");
}

void _807D2E8(){
    asm("mov r0,r0\n");
    asm("JMP807D2E8_r1:\n");
    asm("mov r0,r4\n");
    asm("bl _807D074_end\n");
    asm("add sp,sp,$0x80\n");
    asm("pop {r3,r4}\n");
    asm("mov r8,r3\n");
    asm("mov r9,r4\n");
    asm("pop {r4,r5,r6,r7}\n");
    asm("pop {r0}\n");
    asm("bx r0\n");
}

int unit_is_summon(u32 unit){
    u8 char_id = getb(get(unit)+4);  //角色id;
    u8 *ptr = &sum_data[sum_data_idx*2];
    while(*ptr){
        if(ptr[1]==char_id){
            return 1;
        }
        ptr+= set_item_summon_len;
    }
    return 0;
}

int is_summon(){
    //str(0x0203ffc0,0);
    u8 char_id = getb(get(get(0x3004DF0)+0)+4);  //角色id;
    u8 *ptr = &sum_data[sum_data_idx*2];

    while(*ptr){
        if(ptr[1]==char_id){
            return 1;
        }
        ptr+= set_item_summon_len;
    }
    return 0;
}

//以下是操作召唤物的菜单
u32 _80251CC(uint32_t a1){
    //return 0;  //返回0，则无法交换
    if(is_summon()||unit_is_summon(a1)){
        return 0;
    }

    u8 id = getb(get(get(0x2033F38)+4)+4);  //先获得职业，在获得职业id
    u8 id2 = getb(get(a1+4)+4);             //先获得职业，在获得职业id
    u8 *ptr = summon;
    while(*ptr){
        if(*ptr==id||*ptr==id2){
            return 0;
        }
        ptr ++;
    }
    return CALLT(0x8024D54,getb(get(0x2033F38)+11),getb(a1+11)<<24);
}

// void JMP80252F4_r2(uint32_t a1){
//     ;
// }

//可开启物品栏
int JMP8023280_r2(){
    //return 3;
    u8 id = getb(get(get(0x3004DF0)+4)+4);  //先获得职业，在获得职业id
    #if 0
    //判断职业是否在召唤物中
    u8 *ptr = summon;

    while(*ptr){
        if(*ptr==id){
            return 3;
        }
        ptr ++;
    }
    #else
    //直接判断角色
    if(is_summon()){
        return 3;
    }
    #endif

    if(
        get(get(0x3004DF0)+0xc) & 0x40
        || id == 0x51
        || !geth(get(0x3004DF0)+30)
    ){
        return 3;
    }
    return 1;
}

//0x885d0fc + 4 为召唤物职业的id

//是否显示交换道具的菜单，需要设置召唤物
void __80251CC_r1(int a1){
    asm("mov r0,r0\n");
    asm("JMP80251CC_r1:\n");
    asm("push   {r4,r5,lr}\n");
    asm("mov    r4,r0\n");
    asm("ldr    r5,=0x2033F38\n");
    asm("bl     _80251CC\n");
    asm("ldr r1,=0x80251E2+1\n");
    asm("bx r1\n");
}

u32 _8024390h(u32 a0){
    //((get(get(0x3004DF0)+0x28) |  get(get(get(0x3004DF0)+4)+0x28)) & 0x8000000))

    //return 1;  //表示可以召唤
    //return 3;    //表示不可以召唤

    return 6;  //表示执行内部的程序
}

//显示召唤菜单
void _8024390_r2(){
    asm("mov r0,r0\n");
    asm("JMP8024390_r2:\n");
    asm("push {r4,r5,lr}\n");
    asm("\n");
    asm("bl _8024390h\n");
    asm("cmp r0,#6\n");
    asm("beq _8024390_next\n");
    asm("pop {r4,r5}\n");
    asm("pop {r1}\n");
    asm("bx r1\n");
    asm("\n");
    asm("\n");
    asm("_8024390_next:\n");
    asm("ldr r4,=0x3004DF0\n");
    asm("ldr r2,[r4]\n");
    asm("ldr r0,[r2]\n");
    asm("ldr r1,[r2,#4]\n");
    asm("ldr r0,[r0,#0x28]\n");
    asm("ldr r1,[r1,#0x28]\n");
    asm("ldr r3,=0x802439E+1\n");
    asm("bx r3\n");
}
